package com.ag.improvedjava.utils;

import java.util.Comparator;

import com.ag.improvedjava.iterable.ImprovedIterable;

/***
 * Represents a sorted sequence.
 * @author Guillaume
 *
 * @param <T>
 */
public interface OrderedIterable<T> extends ImprovedIterable<T> {

	/***
	 * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
	 * @param keySelector
	 * @param comparer
	 * @param descending
	 * @return
	 */
	public <K> OrderedIterable<T> createOrderedEnumerable(
			Function<T, K> keySelector, Comparator<K> comparer,
			boolean descending);
	

	/***
	 * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key.
	 * @param keySelector
	 * @return
	 */
	public <K extends Comparable<? super K>> OrderedIterable<T> thenBy(Function<T, K> keySelector); 

	/***
	 * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key, 
	 * using the input comparer to test key equality. 
	 * @param keySelector
	 * @param comparer
	 * @return
	 */
	public <K> OrderedIterable<T> thenBy(Function<T, K> keySelector, Comparator<K> comparer); 

	/***
	 * Performs a subsequent ordering of the elements in a sequence in descending order according to a key.
	 * @param keySelector
	 * @return
	 */
	public <K extends Comparable<? super K>> OrderedIterable<T> thenByDescending(Function<T, K> keySelector); 
	
	/***
	 * Performs a subsequent ordering of the elements in a sequence in ascending order according to a key, 
	 * using the input comparer to test key equality. 
	 * @param keySelector
	 * @param comparer
	 * @return
	 */
	public <K> OrderedIterable<T> thenByDescending(Function<T, K> keySelector, Comparator<K> comparer); 

}
